package com.hydra.framework.event.kvo.list;

import com.hydra.framework.event.kvo.KvoEventIntent;
import com.hydra.framework.event.kvo.KvoSource;

import java.util.List;

/**
 * Created by Hydra.
 *
 */
public class KvoListHelper {

    public static class NSRange {
        public int location;
        public int length;

        public NSRange(int location, int length) {
            this.length = length;
            this.location = location;
        }
    }

    /**
     * list变更的范围
     */
    public static final String KvoEventArg_Array_Key_Range = "KvoEventArg_Range";
    /**
     * list变更的种类，增删改等
     */
    public static final String KvoEventArg_Array_Key_Type = "KvoEventArg_Array_Key_Type";

    public static final int KvoEventArg_Type_Insert = 0;
    public static final int KvoEventArg_Type_Remove = 1;
    public static final int KvoEventArg_Type_Replace = 2;
    public static final int KvoEventArg_Type_Move = 3;
    public static final int KvoEventArg_Type_Reload = 4;

    public static <T> void insert(KvoSource source, String name, List<T> list, int location, int length) {
        notifyKvoArray(source, name, list, KvoEventArg_Type_Insert, new NSRange(location, length));
    }

    public static <T> void rangeRemove(KvoSource source, String name, List<T> list, int location, int length) {
        notifyKvoArray(source, name, list, KvoEventArg_Type_Remove, new NSRange(location, length));
    }

    public static <T> void move(KvoSource source, String name, List<T> list, int oldLocation, int newLocation) {
        notifyKvoArray(source, name, list, KvoEventArg_Type_Move, new NSRange(oldLocation, newLocation - oldLocation));
    }

    public static <T> void rangeReplace(KvoSource source, String name, List<T> list, int location, int length) {
        notifyKvoArray(source, name, list, KvoEventArg_Type_Replace, new NSRange(location, length));
    }

    //reload all
    public static <T> void notifyDataSetChanged(KvoSource source, String name, List<T> list) {
        notifyKvoArray(source, name, list, KvoEventArg_Type_Reload, new NSRange(0, list.size()));
    }

    private static <T> void notifyKvoArray(KvoSource source, String name, List<T> list, int type, NSRange range) {
        KvoEventIntent kvoEventIntent = KvoEventIntent.build(source, name);

        kvoEventIntent.setOldValue(list);
        kvoEventIntent.setNewValue(list);

        kvoEventIntent.putArg(KvoEventArg_Array_Key_Range, range);
        kvoEventIntent.putArg(KvoEventArg_Array_Key_Type, type);

        source.notifyEvent(kvoEventIntent);
    }

    public static NSRange notifyRange(KvoEventIntent intent) {
        return intent.getArgWithKey(KvoEventArg_Array_Key_Range);
    }

    public static int notifyType(KvoEventIntent intent) {
        Integer type = intent.getArgWithKey(KvoEventArg_Array_Key_Type);

        return type == null ? KvoEventArg_Type_Reload : type;
    }
}
